xfree(tree);
}
+static
+int
+compare(const void *a, const void *b)
+{
+ const waypoint *wa = *(waypoint **)a;
+ const waypoint *wb = *(waypoint **)b;
+
+ if ( wa->gc_data.exported < wb->gc_data.exported ) {
+ return 1;
+ } else if ( wa->gc_data.exported > wb->gc_data.exported ) {
+ return -1;
+ }
+ return 0;
+}
+
void
duplicate_process(void)
{
- queue * elem, * tmp;
waypoint * waypointp;
btree_node * newnode, * btmp, * sup_tree = NULL;
unsigned long crc = 0;
struct { char shortname[32]; char lat[13]; char lon[13]; } dupe;
waypoint * delwpt = NULL;
-
+
+ int i, ct = waypt_count();
+ waypoint **htable, **bh;
+ queue *elem, *tmp;
+ extern queue waypt_head;
+
+ htable = xmalloc(ct * sizeof(*htable));
+ bh = htable;
+
QUEUE_FOR_EACH(&waypt_head, elem, tmp) {
- waypointp = (waypoint *) elem;
+ *bh = (waypoint *) elem;
+ bh ++;
+ }
+ qsort(htable, ct, sizeof(*bh), compare);
+ for (i=0;i<ct;i++) {
+ waypointp = htable[i];
+
memset(&dupe, '\0', sizeof(dupe));
if (snopt) {
waypt_free(delwpt);
}
+ xfree(htable);
free_tree(sup_tree);
}
static int in_gs_terr;
static int in_gs_log;
static int in_gs_log_wpt;
+static int in_gs_exported;
static int in_gs_tbugs;
static int in_something_else;
static xml_tag *cur_tag;
static FILE *ofd;
static void *mkshort_handle;
+static time_t file_time;
+
static char *gsshortnames = NULL;
#define MYNAME "GPX"
in_something_else++;
start_something_else( el, attr );
}
+ else if (strcmp(el, "groundspeak:exported") == 0) {
+ in_gs_exported++;
+ /* no start_something_else because the old date is eaten */
+ }
else if (strcmp(el, "groundspeak:travelbugs") == 0) {
in_gs_tbugs++;
in_something_else++;
return gc_unknown;
}
+static
+time_t
+xml_parse_time( char *cdatastr )
+{
+ int off_hr = 0;
+ int off_min = 0;
+ int off_sign = 1;
+ char *offsetstr = NULL;
+ char *pointstr = NULL;
+ struct tm tm;
+ time_t rv = 0;
+ char *timestr = xstrdup( cdatastr );
+
+ offsetstr = strchr( timestr, 'Z' );
+ if ( offsetstr ) {
+ /* zulu time; offsets stay at defaults */
+ *offsetstr = '\0';
+ } else {
+ offsetstr = strchr( timestr, '+' );
+ if ( offsetstr ) {
+ /* positive offset; parse it */
+ *offsetstr = '\0';
+ sscanf( offsetstr+1, "%d:%d", &off_hr, &off_min );
+ } else {
+ offsetstr = strchr( timestr, 'T' );
+ if ( offsetstr ) {
+ offsetstr = strchr( offsetstr, '-' );
+ if ( offsetstr ) {
+ /* negative offset; parse it */
+ *offsetstr = '\0';
+ sscanf( offsetstr+1, "%d:%d",
+ &off_hr, &off_min );
+ off_sign = -1;
+ }
+ }
+ }
+
+ }
+
+ pointstr = strchr( timestr, '.' );
+ if ( pointstr ) {
+ *pointstr = '\0';
+ }
+
+ sscanf(timestr, "%d-%d-%dT%d:%d:%d",
+ &tm.tm_year,
+ &tm.tm_mon,
+ &tm.tm_mday,
+ &tm.tm_hour,
+ &tm.tm_min,
+ &tm.tm_sec);
+ tm.tm_mon -= 1;
+ tm.tm_year -= 1900;
+ tm.tm_isdst = 0;
+
+ rv = mktime(&tm) + get_tz_offset() - off_sign*off_hr*3600 -
+ off_sign*off_min*60;
+
+ xfree(timestr);
+
+ return rv;
+}
+
static void
gpx_end(void *data, const char *el)
{
sscanf(cdatastr, "%lf",
&wpt_tmp->position.altitude.altitude_meters);
}
- if (in_time && (in_wpt || in_rte)) {
- struct tm tm;
- sscanf(cdatastr, "%d-%d-%dT%d:%d:%dZ\n",
- &tm.tm_year,
- &tm.tm_mon,
- &tm.tm_mday,
- &tm.tm_hour,
- &tm.tm_min,
- &tm.tm_sec);
- tm.tm_mon -= 1;
- tm.tm_year -= 1900;
- tm.tm_isdst = 1;
- wpt_tmp->creation_time = mktime(&tm) + get_tz_offset();
+ if (in_time) {
+ if ( in_wpt || in_rte) {
+ wpt_tmp->creation_time =
+ xml_parse_time( cdatastr );
+ }
+ else {
+ file_time = xml_parse_time( cdatastr );
+ }
}
if (in_wpt && in_gs_type && !in_gs_log) {
wpt_tmp->gc_data.type = gs_mktype(cdatastr);
sscanf(cdatastr, "%f", &x);
wpt_tmp->gc_data.terr = x * 10;
}
+ if (in_gs_exported && in_wpt ) {
+ wpt_tmp->gc_data.exported = xml_parse_time( cdatastr );
+ }
in_cdata--;
memset(cdatastr, 0, MY_CBUF);
}
if (strcmp(el, "wpt") == 0) {
+ if ( !wpt_tmp->gc_data.exported ) {
+ wpt_tmp->gc_data.exported = file_time;
+ }
waypt_add(wpt_tmp);
in_wpt--;
logpoint_ct = 0;
in_gs_log_wpt--;
in_something_else--;
end_something_else();
+ } else if (strcmp(el, "groundspeak:exported") == 0) {
+ in_gs_exported--;
+ /* no end_something_else because the old date is eaten */
} else if (strcmp(el, "groundspeak:travelbugs") == 0) {
in_gs_tbugs--;
in_something_else--;
(in_wpt && in_gs_diff) ||
(in_wpt && in_gs_terr) ||
(in_wpt && in_icon) ||
- (in_time && (in_wpt || in_rte))) {
+ (in_time)) {
estr = cdatastr + strlen(cdatastr);
memcpy(estr, s, len);
in_cdata++;
if (get_option(args, "logpoint") != NULL)
opt_logpoint = 1;
+ file_time = 0;
+
psr = XML_ParserCreate(NULL);
if (!psr) {
fatal(MYNAME ": Cannot create XML Parser\n");
*/
static
void
-gpx_write_time(const time_t timep)
+gpx_write_time(const time_t timep, char *elname)
{
struct tm *tm = gmtime(&timep);
if (!tm)
return;
- fprintf(ofd, "<time>%02d-%02d-%02dT%02d:%02d:%02dZ</time>\n",
+ fprintf(ofd, "<%s>%02d-%02d-%02dT%02d:%02d:%02dZ</%s>\n",
+ elname,
tm->tm_year+1900,
tm->tm_mon+1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
- tm->tm_sec
+ tm->tm_sec,
+ elname
);
}
}
static void
-fprint_xml_chain( xml_tag *tag )
+fprint_xml_chain( xml_tag *tag, const waypoint *wpt )
{
char *tmp_ent;
while ( tag ) {
xfree(tmp_ent);
}
if ( tag->child ) {
- fprint_xml_chain(tag->child);
+ fprint_xml_chain(tag->child, wpt);
+ }
+ if ( strcmp(tag->tagname, "groundspeak:cache" ) == 0
+ && wpt->gc_data.exported) {
+ gpx_write_time( wpt->gc_data.exported,
+ "groundspeak:exported" );
}
fprintf( ofd, "</%s>", tag->tagname);
if ( tag->parentcdata ) {
waypointp->position.altitude.altitude_meters);
}
if (waypointp->creation_time) {
- gpx_write_time(waypointp->creation_time);
+ gpx_write_time(waypointp->creation_time, "time");
}
if (waypointp->url) {
tmp_ent = gpx_entitize(waypointp->url);
xfree(tmp_ent);
}
- fprint_xml_chain( waypointp->gpx_extras);
+ fprint_xml_chain( waypointp->gpx_extras, waypointp );
fprintf(ofd, "</wpt>\n");
}
waypointp->position.latitude.degrees,
waypointp->position.longitude.degrees);
if (waypointp->creation_time) {
- gpx_write_time(waypointp->creation_time);
+ gpx_write_time(waypointp->creation_time,"time");
}
if (waypointp->position.altitude.altitude_meters != unknown_alt) {
fprintf(ofd, "<ele>\n%f\n</ele>\n",
void
gpx_write(void)
{
+ time_t now = 0;
+
+ time( &now );
setshort_length(mkshort_handle, 32);
fprintf(ofd, "<?xml version=\"1.0\"?>\n");
fprintf(ofd, "xmlns=\"http://www.topografix.com/GPX/1/0\"\n");
fprintf(ofd, "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n");
+ gpx_write_time( now, "time" );
switch(global_opts.objective) {
case trkdata: gpx_track_pr();
case wptdata: waypt_disp_all(gpx_waypt_pr);